home *** CD-ROM | disk | FTP | other *** search
- // dibapi.cpp
- //
- // Source file for Device-Independent Bitmap (DIB) API. Provides
- // the following functions:
- //
- // PaintDIB() - Painting routine for a DIB
- // CreateDIBPalette() - Creates a palette from a DIB
- // DIBWidth() - Gets the width of the DIB
- // DIBHeight() - Gets the height of the DIB
- // PaletteSize() - Gets the size required to store the DIB's palette
- // DIBNumColors() - Calculates the number of colors
- // in the DIB's color table
- //
- // This is a part of the Microsoft Foundation Classes C++ library.
- // Copyright (C) 1999 Microsoft Corporation
- // All rights reserved.
- //
- // This source code is only intended as a supplement to the
- // Microsoft Foundation Classes Reference and related
- // electronic documentation provided with the library.
- // See these sources for detailed information regarding the
- // Microsoft Foundation Classes product.
-
- #include "stdafx.h"
- #include "dibapi.h"
-
- #include "mainfrm.h"
-
- /*************************************************************************
- *
- * PaintDIB()
- *
- * Parameters:
- *
- * HDC hDC - DC to do output to
- *
- * LPRECT lpDCRect - rectangle on DC to do output to
- *
- * HDIB hDIB - handle to global memory with a DIB spec
- * in it followed by the DIB bits
- *
- * LPRECT lpDIBRect - rectangle of DIB to output into lpDCRect
- *
- * CPalette* pPal - pointer to CPalette containing DIB's palette
- *
- * Return Value:
- *
- * BOOL - TRUE if DIB was drawn, FALSE otherwise
- *
- * Description:
- * Painting routine for a DIB. Calls StretchDIBits() or
- * SetDIBitsToDevice() to paint the DIB. The DIB is
- * output to the specified DC, at the coordinates given
- * in lpDCRect. The area of the DIB to be output is
- * given by lpDIBRect.
- *
- ************************************************************************/
-
- BOOL WINAPI PaintDIB(HDC hDC,
- LPRECT lpDCRect,
- HDIB hDIB,
- LPRECT lpDIBRect,
- CPalette* pPal)
- {
- LPSTR lpDIBHdr; // Pointer to BITMAPINFOHEADER
- LPSTR lpDIBBits; // Pointer to DIB bits
- BOOL bSuccess=FALSE; // Success/fail flag
- HPALETTE hPal=NULL; // Our DIB's palette
- HPALETTE hOldPal=NULL; // Previous palette
-
- /* Check for valid DIB handle */
- if (hDIB == NULL)
- return FALSE;
-
- /* Lock down the DIB, and get a pointer to the beginning of the bit
- * buffer
- */
- lpDIBHdr = (LPSTR)hDIB;
- lpDIBBits = (lpDIBHdr + *(LPDWORD)lpDIBHdr + ::PaletteSize(lpDIBHdr));
-
- // Get the DIB's palette, then select it into DC
- if (pPal != NULL)
- {
- hPal = (HPALETTE) pPal->m_hObject;
-
- // Select as background since we have
- // already realized in forground if needed
- hOldPal = ::SelectPalette(hDC, hPal, TRUE);
- }
-
- HDC hDCSrc = CreateCompatibleDC(hDC);
-
- LPSTR lpBits; // Pointer to DIB bits
-
- HBITMAP hBitmap = ::CreateDIBSection(hDC, (BITMAPINFO*)(lpDIBHdr), DIB_RGB_COLORS, (void**)&lpBits, NULL, 0);
- DWORD dwSize = GlobalSize(hDIB) - sizeof(BITMAPINFOHEADER) - 256 * sizeof(RGBQUAD) - 24;
- memcpy(lpBits, lpDIBBits, dwSize);
-
-
- HBITMAP hOldBitmap = (HBITMAP)::SelectObject(hDCSrc, (HGDIOBJ)hBitmap);
- ::BitBlt( hDC, 0, 0, RECTWIDTH(lpDCRect), RECTHEIGHT(lpDCRect), hDCSrc, 0, 0, SRCCOPY );
- ::SelectObject(hDCSrc, hOldBitmap);
-
-
- ::DeleteObject(hBitmap);
- ::DeleteDC(hDCSrc);
-
- /* Reselect old palette */
- if (hOldPal != NULL)
- ::SelectPalette(hDC, hOldPal, TRUE);
-
- return bSuccess;
- }
-
- /*************************************************************************
- *
- * CreateDIBPalette()
- *
- * Parameter:
- *
- * HDIB hDIB - specifies the DIB
- *
- * Return Value:
- *
- * HPALETTE - specifies the palette
- *
- * Description:
- *
- * This function creates a palette from a DIB by allocating memory for the
- * logical palette, reading and storing the colors from the DIB's color table
- * into the logical palette, creating a palette from this logical palette,
- * and then returning the palette's handle. This allows the DIB to be
- * displayed using the best possible colors (important for DIBs with 256 or
- * more colors).
- *
- ************************************************************************/
-
-
- BOOL WINAPI CreateDIBPalette(HDIB hDIB, CPalette* pPal)
- {
- LPLOGPALETTE lpPal; // pointer to a logical palette
- HANDLE hLogPal; // handle to a logical palette
- HPALETTE hPal = NULL; // handle to a palette
- int i; // loop index
- WORD wNumColors; // number of colors in color table
- LPSTR lpbi; // pointer to packed-DIB
- LPBITMAPINFO lpbmi; // pointer to BITMAPINFO structure
- BOOL bResult = FALSE;
-
- /* if handle to DIB is invalid, return FALSE */
-
- if (hDIB == NULL)
- return FALSE;
-
- lpbi = (LPSTR)hDIB;
-
- /* get pointer to BITMAPINFO */
- lpbmi = (LPBITMAPINFO)lpbi;
-
- /* get the number of colors in the DIB */
- wNumColors = ::DIBNumColors(lpbi);
-
- if (wNumColors != 0)
- {
- /* allocate memory block for logical palette */
- hLogPal = ::GlobalAlloc(GHND, sizeof(LOGPALETTE)
- + sizeof(PALETTEENTRY)
- * wNumColors);
-
- /* if not enough memory, clean up and return NULL */
- if (hLogPal == 0)
- return FALSE;
-
- lpPal = (LPLOGPALETTE)hLogPal;
-
- /* set version and number of palette entries */
- lpPal->palVersion = PALVERSION;
- lpPal->palNumEntries = (WORD)wNumColors;
-
- for (i = 0; i < (int)wNumColors; i++)
- {
- lpPal->palPalEntry[i].peRed = lpbmi->bmiColors[i].rgbRed;
- lpPal->palPalEntry[i].peGreen = lpbmi->bmiColors[i].rgbGreen;
- lpPal->palPalEntry[i].peBlue = lpbmi->bmiColors[i].rgbBlue;
- lpPal->palPalEntry[i].peFlags = 0;
- }
-
- /* create the palette and get handle to it */
- bResult = pPal->CreatePalette(lpPal);
- ::GlobalFree((HGLOBAL) hLogPal);
- }
-
- return bResult;
- }
-
-
- /*************************************************************************
- *
- * DIBWidth()
- *
- * Parameter:
- *
- * LPSTR lpbi - pointer to packed-DIB memory block
- *
- * Return Value:
- *
- * DWORD - width of the DIB
- *
- * Description:
- *
- * This function gets the width of the DIB from the BITMAPINFOHEADER
- *
- ************************************************************************/
-
-
- DWORD WINAPI DIBWidth(LPSTR lpDIB)
- {
- LPBITMAPINFOHEADER lpbmi = (LPBITMAPINFOHEADER)lpDIB;
- return lpbmi->biWidth;
- }
-
-
- /*************************************************************************
- *
- * DIBHeight()
- *
- * Parameter:
- *
- * LPSTR lpbi - pointer to packed-DIB memory block
- *
- * Return Value:
- *
- * DWORD - height of the DIB
- *
- * Description:
- *
- * This function gets the height of the DIB from the BITMAPINFOHEADER
- *
- ************************************************************************/
-
-
- DWORD WINAPI DIBHeight(LPSTR lpDIB)
- {
- LPBITMAPINFOHEADER lpbmi = (LPBITMAPINFOHEADER)lpDIB;
- return lpbmi->biHeight;
- }
-
-
- /*************************************************************************
- *
- * PaletteSize()
- *
- * Parameter:
- *
- * LPSTR lpbi - pointer to packed-DIB memory block
- *
- * Return Value:
- *
- * WORD - size of the color palette of the DIB
- *
- * Description:
- *
- * This function gets the size required to store the DIB's palette by
- * multiplying the number of colors by the size of an RGBQUAD
- *
- ************************************************************************/
-
-
- WORD WINAPI PaletteSize(LPSTR lpbi)
- {
- return (WORD)(::DIBNumColors(lpbi) * sizeof(RGBQUAD));
- }
-
-
- /*************************************************************************
- *
- * DIBNumColors()
- *
- * Parameter:
- *
- * LPSTR lpbi - pointer to packed-DIB memory block
- *
- * Return Value:
- *
- * WORD - number of colors in the color table
- *
- * Description:
- *
- * This function calculates the number of colors in the DIB's color table
- * by finding the bits per pixel for the DIB. If bits per pixel is 1:
- * colors=2, if 4: colors=16, if 8: colors=256, if 24, no colors in color
- * table.
- *
- ************************************************************************/
-
-
- WORD WINAPI DIBNumColors(LPSTR lpbi)
- {
- WORD wBitCount; // DIB bit count
-
- /* If this is a Windows-style DIB, the number of colors in the
- * color table can be less than the number of bits per pixel
- * allows for (i.e. lpbi->biClrUsed can be set to some value).
- * If this is the case, return the appropriate value.
- */
-
- DWORD dwClrUsed;
-
- dwClrUsed = ((LPBITMAPINFOHEADER)lpbi)->biClrUsed;
- if (dwClrUsed != 0)
- return (WORD)dwClrUsed;
-
- /* Calculate the number of colors in the color table based on
- * the number of bits per pixel for the DIB.
- */
- wBitCount = ((LPBITMAPINFOHEADER)lpbi)->biBitCount;
- /* return number of colors based on bits per pixel */
- switch (wBitCount)
- {
- case 1:
- return 2;
- case 4:
- return 16;
- case 8:
- return 256;
- default:
- return 0;
- }
- }
-
-